package com.fowo.api.walmart.api;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fowo.api.datainterface.constants.Constants;
import com.fowo.api.datainterface.service.impl.DatainterfaceServiceImpl;
import com.fowo.api.entity.ShopInfo;
import com.fowo.api.entity.TmpWalmartOrder;
import com.fowo.api.entity.TmpWalmartOrderGoods;
import com.fowo.api.mapper.ShopInfoMapper;
import com.fowo.api.model.nav.sell.order.NavSellOrderVo;
import com.fowo.api.model.nav.sell.order.detail.NavSellOrderDetailItemVo;
import com.fowo.api.model.shop.info.ShopInfoVo;
import com.fowo.api.service.CarrierService;
import com.fowo.api.service.impl.TmpWalmartOrderGoodsServiceImpl;
import com.fowo.api.service.impl.TmpWalmartOrderServiceImpl;
import com.fowo.api.walmart.entity.*;
import com.fowo.api.walmart.util.WalmartUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.*;

@Component
@Slf4j
public class WalmartApi {

    @Resource
    private ShopInfoMapper shopInfoMapper;
    @Resource
    private TmpWalmartOrderServiceImpl tmpWalmartOrderService;
    @Resource
    private TmpWalmartOrderGoodsServiceImpl tmpWalmartOrderGoodsService;
    @Resource
    private CarrierService carrierService;
    @Resource
    private DatainterfaceServiceImpl datainterfaceService;

    private static final String ORDER_URL = "https://marketplace.walmartapis.com/v3/orders";

    public void getOrder(GetOrderDto getOrderDto) {
        final List<ShopInfo> shopInfos = shopInfoMapper.selectList(Wrappers.lambdaQuery(ShopInfo.class)
                .eq(ShopInfo::getPlatform, "Walmart")
                .eq(ShopInfo::getSellerAuthStatus, "SQ01"));
        for (ShopInfo shopInfo : shopInfos) {

            String token = WalmartUtil.getToken(shopInfo.getMarketplaceId(), shopInfo.getRefreshToken());
            Map<String,String> header = new HashMap<>();
            header.put("WM_SEC.ACCESS_TOKEN", token);
            header.put("WM_QOS.CORRELATION_ID", UUID.randomUUID().toString());
            header.put("WM_SVC.NAME", "Walmart Marketplace");

            Map<String, Object> param = new HashMap<>();

            String limit = "200";
            if (getOrderDto != null) {
                if (StringUtils.isBlank(getOrderDto.getLimit())) {
                    getOrderDto.setLimit(limit);
                }
                Class clazz = getOrderDto.getClass();
                Field[] fields = clazz.getDeclaredFields();
                try {
                    for (Field field : fields) {
                        field.setAccessible(true);
                        if(field.get(getOrderDto) != null){
                            param.put(field.getName(), field.get(getOrderDto));
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                param.put("limit", limit);
                param.put("productInfo", "true");
            }

            final Object res = datainterfaceService.executeInterface(null, "EC00524", null, param, header);
            JSONObject body = JSONUtil.parseObj(res);
            log.info("订单列表返回参数：{}", JSONUtil.toJsonStr(body));

            final JSONObject list = body.getJSONObject("list");
            Assert.notNull(list, "获取沃尔玛订单异常");
            final JSONArray orders = list.getJSONObject("elements").getJSONArray("order");

            final JSONObject meta = list.getJSONObject("meta");
            if (StrUtil.isNotEmpty(meta.getStr("nextCursor"))) {
                String nextCursor = meta.getStr("nextCursor");
                getNextOrder(nextCursor, header, orders);
            }
            //保存订单到临时表
            buildOrder(orders, shopInfo);
        }
    }

    /**
     * 下一页
     *
     * @param next
     * @param header
     * @param orders
     */
    private void getNextOrder(String next, Map<String,String> header, JSONArray orders) {
        Map<String, Object> param = new HashMap<>();
        param.put("next",next);
        final Object result = datainterfaceService.executeInterface(null, "EC00524", null, param, header);
        JSONObject body = JSONUtil.parseObj(result);

        final JSONObject list = body.getJSONObject("list");
        Assert.notNull(list, "获取沃尔玛订单异常");
        final JSONArray nextOrders = list.getJSONObject("elements").getJSONArray("order");
        orders.addAll(nextOrders);
        final JSONObject meta = list.getJSONObject("meta");
        if (StrUtil.isNotEmpty(meta.getStr("nextCursor"))) {
            String nextCursor = meta.getStr("nextCursor");
            getNextOrder(nextCursor, header, orders);
        }
    }

//    public void getOrder(GetOrderDto getOrderDto) {
//        final List<ShopInfo> shopInfos = shopInfoMapper.selectList(Wrappers.lambdaQuery(ShopInfo.class)
//                .eq(ShopInfo::getPlatform, "Walmart")
//                .eq(ShopInfo::getSellerAuthStatus, "SQ01"));
//        for (ShopInfo shopInfo : shopInfos) {
//
//            String token = WalmartUtil.getToken(shopInfo.getMarketplaceId(), shopInfo.getRefreshToken());
//
//            HttpHeaders header = new HttpHeaders();
//            header.set("WM_SEC.ACCESS_TOKEN", token);
//            header.set("WM_QOS.CORRELATION_ID", UUID.randomUUID().toString());
//            header.set("WM_SVC.NAME", "Walmart Marketplace");
//
//            Map<String, Object> param = new HashMap<>();
//
//            String limit = "200";
//            if (getOrderDto != null) {
//                if (StringUtils.isBlank(getOrderDto.getLimit())) {
//                    getOrderDto.setLimit(limit);
//                }
//                Class clazz = getOrderDto.getClass();
//                Field[] fields = clazz.getDeclaredFields();
//                try {
//                    for (Field field : fields) {
//                        field.setAccessible(true);
//                        param.put(field.getName(), field.get(getOrderDto));
//                    }
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            } else {
//                param.put("limit", limit);
//                param.put("productInfo", "true");
//            }
//            Object result = WalmartUtil.getBaseAspect().httpRequest(ORDER_URL, HttpMethod.GET, JSONUtil.toJsonStr(param), header, Object.class, Constants.Read, StrUtil.EMPTY);
//            JSONObject body = JSONUtil.parseObj(result);
//            log.error("订单列表返回参数：{}", JSONUtil.toJsonStr(body));
//
//            final JSONObject list = body.getJSONObject("list");
//            Assert.notNull(list, "获取沃尔玛订单异常");
//            final JSONArray orders = list.getJSONObject("elements").getJSONArray("order");
//
//            final JSONObject meta = list.getJSONObject("meta");
//            if (StrUtil.isNotEmpty(meta.getStr("nextCursor"))) {
//                String nextCursor = meta.getStr("nextCursor");
//                getNextOrder(nextCursor, header, orders);
//            }
//            //保存订单到临时表
//            buildOrder(orders, shopInfo);
//        }
//    }

//    private void getNextOrder(String next, HttpHeaders header, JSONArray orders) {
//        String url = ORDER_URL + next;
//        Object result = WalmartUtil.getBaseAspect().httpRequest(url, HttpMethod.GET, null, header, Object.class, Constants.Read, StrUtil.EMPTY);
//        JSONObject body = JSONUtil.parseObj(result);
//
//        final JSONObject list = body.getJSONObject("list");
//        Assert.notNull(list, "获取沃尔玛订单异常");
//        final JSONArray nextOrders = list.getJSONObject("elements").getJSONArray("order");
//        orders.addAll(nextOrders);
//        final JSONObject meta = list.getJSONObject("meta");
//        if (StrUtil.isNotEmpty(meta.getStr("nextCursor"))) {
//            String nextCursor = meta.getStr("nextCursor");
//            getNextOrder(nextCursor, header, orders);
//        }
//    }

    /**
     * 保存到临时表
     * @param orders
     * @param shop
     */
    public void buildOrder(JSONArray orders, ShopInfo shop) {
        CopyOptions copyOptions = CopyOptions.create();
        copyOptions.setOverride(false);
        copyOptions.setIgnoreNullValue(true);

        List<TmpWalmartOrder> orderList = new ArrayList();
        List<TmpWalmartOrderGoods> goodsList = new ArrayList<>();
        for (int i = 0; i < orders.size(); i++) {
            final JSONObject orderObject = orders.getJSONObject(i);
            //订单基础信息
            TmpWalmartOrder tmpWalmartOrder = JSONUtil.toBean(orderObject, TmpWalmartOrder.class);
            //订单发货信息
            final JSONObject shippingInfo = orderObject.getJSONObject("shippingInfo");
            TmpWalmartOrder orderShippingInfo = JSONUtil.toBean(shippingInfo, TmpWalmartOrder.class);
            BeanUtil.copyProperties(orderShippingInfo, tmpWalmartOrder, copyOptions);
            //订单发货地址信息
            final JSONObject postalAddress = shippingInfo.getJSONObject("postalAddress");
            TmpWalmartOrder orderAddress = JSONUtil.toBean(postalAddress, TmpWalmartOrder.class);
            BeanUtil.copyProperties(orderAddress, tmpWalmartOrder, copyOptions);

            tmpWalmartOrder.setSid(shop.getId());
            tmpWalmartOrder.setRegion(shop.getRegion());
            tmpWalmartOrder.setCreateTime(new Date());
            tmpWalmartOrder.setLastUpdateTime(new Date());
            JSONObject shipNode = orderObject.getJSONObject("shipNode");
            if (null != shipNode) {
                String type = shipNode.getStr("type");
                tmpWalmartOrder.setShipType(type);
            }
            orderList.add(tmpWalmartOrder);
            //订单产品信息
            JSONArray orderLineArray = orderObject.getJSONObject("orderLines").getJSONArray("orderLine");
            for (int j = 0; j < orderLineArray.size(); j++) {
                final JSONObject orderLineJsonObject = orderLineArray.getJSONObject(j);
                final JSONObject orderLineStatuses = orderLineJsonObject.getJSONObject("orderLineStatuses");
                final JSONArray orderLineStatus = orderLineStatuses.getJSONArray("orderLineStatus");
                if (null != orderLineStatus) {
                    JSONObject jsonObject = orderLineStatus.getJSONObject(0);
                    String status = jsonObject.getStr("status");
                    tmpWalmartOrder.setOrderStatus(status);
                }
                TmpWalmartOrderGoods tmpWalmartOrderGoods = JSONUtil.toBean(orderLineJsonObject, TmpWalmartOrderGoods.class);

                final JSONObject item = orderLineJsonObject.getJSONObject("item");
                TmpWalmartOrderGoods goodsItem = JSONUtil.toBean(item, TmpWalmartOrderGoods.class);
                BeanUtil.copyProperties(goodsItem, tmpWalmartOrderGoods, copyOptions);

                final JSONObject orderLineQuantity = orderLineJsonObject.getJSONObject("orderLineQuantity");
                tmpWalmartOrderGoods.setUnitOfMeasurement(orderLineQuantity.getStr("unitOfMeasurement"));
                tmpWalmartOrderGoods.setAmount(orderLineQuantity.getStr("amount"));

                final JSONObject fulfillment = orderLineJsonObject.getJSONObject("fulfillment");
                TmpWalmartOrderGoods goodsFulfillment = JSONUtil.toBean(fulfillment, TmpWalmartOrderGoods.class);
                BeanUtil.copyProperties(goodsFulfillment, tmpWalmartOrderGoods, copyOptions);

                tmpWalmartOrderGoods.setCustomerOrderId(tmpWalmartOrder.getCustomerOrderId());
                tmpWalmartOrderGoods.setPurchaseOrderId(tmpWalmartOrder.getPurchaseOrderId());
                tmpWalmartOrderGoods.setCreateTime(new Date());
                tmpWalmartOrderGoods.setLastUpdateTime(new Date());
                goodsList.add(tmpWalmartOrderGoods);
            }

        }
        tmpWalmartOrderService.saveBatch(orderList);
        tmpWalmartOrderGoodsService.saveBatch(goodsList);

    }

    /**
     * 订单标发
     *
     * @param navSellOrderVo
     */
    public void shipOrder(NavSellOrderVo navSellOrderVo) {
        String purchaseOrderId = navSellOrderVo.getPlatform().get(0).getPlatformOrderId();
//        String url = "https://marketplace.walmartapis.com/v3/orders/" + purchaseOrderId + "/shipping";
        final ShopInfoVo shopInfo = shopInfoMapper.selectVoById(navSellOrderVo.getShopInfo());
        String token = WalmartUtil.getToken(shopInfo.getMarketplaceId(), shopInfo.getRefreshToken());
        Map<String,Object> header = new HashMap<>();
        header.put("WM_SEC.ACCESS_TOKEN", token);
        header.put("WM_QOS.CORRELATION_ID", UUID.randomUUID().toString());
        header.put("WM_SVC.NAME", "Walmart Marketplace");

        final List<NavSellOrderDetailItemVo> products = navSellOrderVo.getProduct();
//        tmpWalmartOrderGoodsService.list();
        List<OrderLineBo> list = new ArrayList<>();
        for (NavSellOrderDetailItemVo detailItem : products) {
            OrderLineBo line = new OrderLineBo();
            line.setLineNumber(detailItem.getLineNumber());
            line.setSellerOrderId(detailItem.getSellerOrderId());

            List<OrderLineStatusBo> orderLineStatusList = new ArrayList<>();
            OrderLineStatusBo orderLineStatusBo = new OrderLineStatusBo();
            orderLineStatusBo.setStatus("Shipped");
            // 状态更新的详细信息
            OrderStatusQuantityBo orderStatusQuantityBo = new OrderStatusQuantityBo();
            orderStatusQuantityBo.setUnitOfMeasurement(detailItem.getUnitOfMeasurement());
            orderStatusQuantityBo.setAmount(detailItem.getQuantity().toString());
            orderLineStatusBo.setStatusQuantity(orderStatusQuantityBo);
            //关于包裹运输和跟踪更新的信息列表
            OrderTrackingInfoBo orderTrackingInfoBo = new OrderTrackingInfoBo();
            orderTrackingInfoBo.setShipDateTime(navSellOrderVo.getIssuTime().getTime());
            orderTrackingInfoBo.setMethodCode("Value");
            orderTrackingInfoBo.setTrackingNumber(navSellOrderVo.getDeliveryWaybillId());
            //承运商
            OrderCarrierNameBo orderCarrierNameBo = new OrderCarrierNameBo();
            orderCarrierNameBo.setCarrier(carrierService.getNameById(ObjUtil.isEmpty(CollUtil.getFirst(navSellOrderVo.getPlatform())) ? null : CollUtil.getFirst(navSellOrderVo.getPlatform()).getCarrier()));
            orderTrackingInfoBo.setCarrierName(orderCarrierNameBo);
            orderLineStatusBo.setTrackingInfo(orderTrackingInfoBo);
            orderLineStatusList.add(orderLineStatusBo);

            line.setOrderLineStatus(orderLineStatusList);
            list.add(line);
        }

        Map<String, Object> orderLines = new HashMap<>();
        orderLines.put("orderLine", list);

        Map<String, Object> orderShipment = new HashMap<>();
        orderShipment.put("orderLines", orderLines);

        Map<String, Object> param = new HashMap<>();
        param.put("orderShipment", orderShipment);
//        Object result = WalmartUtil.getBaseAspect().httpRequest(url, HttpMethod.POST, JSONUtil.toJsonStr(param), header, Object.class, Constants.Read, StrUtil.EMPTY);
//        JSONObject body = JSONUtil.parseObj(result);

        param.put("path",purchaseOrderId);
//        final Object result = datainterfaceService.executeInterface(null, "EC00532", null, param, header);
//        JSONObject body = JSONUtil.parseObj(result);
    }
}
